﻿
#region 作者和版权
/*************************************************************************************
* CLR 版本: 4.0.30319.42000
* 类 名 称: ThreadAction
* 机器名称: SUNTIA-QL
* 命名空间: ServerFramework.ThreadUtil
* 文 件 名: ThreadAction
* 创建时间: 2015/9/24 15:49:08
* 作 者: 乔龙 Qiaolong
* 版 权: ThreadAction说明：本代码版权归乔龙所有，使用时必须带上乔龙网站地址 All Rights Reserved (C) 2015 - 2013
* 签 名: To be or not, it is not a problem !
* 网 站: http://www.suntia.net
* 邮 箱: qiaolong306@qq.com 
* 唯一标识： bae5ada5-f030-4019-8ce6-dbcb78280331 
*
* 登录用户: simida
* 所 属 域: SUNTIA-QL

* 创建年份: 2015
* 修改时间:
* 修 改 人:
* 
************************************************************************************/
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using ServerFramework.Tools;


namespace ServerFramework.ThreadUtil
{
    /// <summary>
    /// 所有逻辑限定在一个线程里面游戏循环
    /// </summary>
    public class GameLoop : IDisposable
    {
        /// <summary>
        /// 游戏循环id
        /// </summary>
        public int gameLoopId;
        /// <summary>
        /// 执行线程
        /// </summary>
        private Task _task = null;
        /// <summary>
        /// 线程队列
        /// </summary>
        private ConcurrentQueue<Action> _actionQueue = new ConcurrentQueue<Action>();

        /// <summary>
        /// 循环委托
        /// </summary>
        private Action<float> _updateAction = null;

        /// <summary>
        /// 是否执行循环
        /// </summary>
        private bool _isRun = false;


        public GameLoop()
        {
        }

        public GameLoop(Action<float> updateAction)
        {
            _updateAction = updateAction;
        }

        /// <summary>
        /// 开始游戏循环
        /// </summary>
        public void Start()
        {
            _task = new Task(Update);
            _isRun = true;
            _task.Start();
        }

        /// <summary>
        /// 执行一个逻辑
        /// </summary>
        /// <param name="act"></param>
        public void Execute(Action act)
        {
            _actionQueue.Enqueue(act);
        }

        /// <summary>
        /// 游戏循环
        /// </summary>
        private void Update()
        {
            var lastTime = DateTime.Now;
            float deltaTime = 0;
            while(_isRun)
            {
                try
                {
                    var currTime = DateTime.Now;
                    if (_updateAction != null)
                    {
                        _updateAction(deltaTime);
                    }
                    deltaTime = (float)((currTime - lastTime).TotalSeconds);
                    lastTime = currTime;
                    Action act = null;
                    if (_actionQueue.TryDequeue(out act))
                    {
                        act();
                    }
                    Thread.Sleep(10);
                }
                catch (Exception e)
                {
                    Log.WriteLog(ELogLevel.LOG_ERROR, e);
                }
            }
        }

        public void Dispose()
        {
            Stop();
        }

        public void Stop()
        {
            _isRun = false;
        }
    }
}


